type MapValue = { expire: number; data: any };
/**
 * 挂载在app和agent上的用于用户缓存数据操作的map
 */
export default class AppCache {
	private map = new Map<string, MapValue>();
	private config: {
		appCache?: {
			/** 清理已过期缓存的间隔 */
			clearInterval?: number;
		};
	};
	constructor(config?: Record<string, any>) {
		this.config = config || {};
		this.startTimeoutClear();
	}

	static init(config?: Record<string, any>) {
		return new AppCache(config || {});
	}

	/**
	 * 添加一个缓存
	 *
	 * @param {string} key 字段key，注意不能重复
	 * @param {*} value
	 * @param {number} seconds 缓存时间，按s为单位 默认20s
	 * @memberof AppCache
	 */
	set(key: string, value: any, seconds: number = 20) {
		const expire = new Date(Date.now() + seconds * 1000).getTime();
		this.map.set(key, { expire, data: value });
		return true;
	}

	/**
	 * 获取缓存
	 *
	 * @template T
	 * @param {string} key
	 * @return {*}  {(T | null)}
	 * @memberof AppCache
	 */
	get<T extends any>(key: string): T | null {
		const val = this.map.get(key);
		if (!val) return null;
		if (val.expire < Date.now()) {
			this.map.delete(key);
			return null;
		}
		return val.data;
	}

	remove(key: string) {
		return this.map.delete(key);
	}

	delete(key: string) {
		return this.remove(key);
	}

	/**
	 * 移除已失效的缓存
	 */
	removeExpired() {
		const keys: string[] = [];
		this.map.forEach((value, key) => {
			if (value.expire < Date.now()) {
				keys.push(key);
			}
		});
		for (const key of keys) {
			this.map.delete(key);
		}
		return true;
	}

	reset() {
		this.map.clear();
		this.map = new Map<string, MapValue>();
	}

	clear() {
		this.reset();
	}

	/** 定时清理缓存 */
	private startTimeoutClear() {
		const interval = this?.config?.appCache?.clearInterval || 1000 * 60 * 60 * 12;
		setTimeout(() => {
			this.removeExpired();
			this.startTimeoutClear();
		}, interval);
	}
}
